package com.hp.springbootwebflux.exception;


import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.omg.CORBA.portable.ApplicationException;
import org.springframework.validation.BindException;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.support.WebExchangeBindException;

import javax.validation.ValidationException;
import java.util.HashMap;
import java.util.stream.Collectors;

/**
 * 全局异常信息
 *
 * @author dongxing
 **/
//@ControllerAdvice
@Slf4j
public class GlobalDefaultExceptionHandler {

    /**
     * ORB 和 stub 之间的应用程序级异常
     *
     * @param e
     * @return
     */
    @ExceptionHandler(value = {ApplicationException.class})
    @ResponseBody
    public Result applicationException(ApplicationException e) {
        log.error("Application Exception: "+e);
        return Result.createByErrorCodeMessage(Result.ResponseCode.BAD_REQUEST.getCode(), e.getMessage());
    }


    /**
     * 方法参数效验异常
     *
     * @param e
     * @return
     */
    @ExceptionHandler(value = WebExchangeBindException.class)
    @ResponseBody
    public Result methodArgumentNotValidException(WebExchangeBindException e) {
        log.error("Argument not valid:", e);
        log.error(JSON.toJSONString(e.getBindingResult().getAllErrors()));
        return Result.createByError(Result.ResponseCode.BAD_REQUEST.getCode(), e.getFieldErrors().stream().collect(HashMap::new,(m,v)->m.put(v.getField(),v.getDefaultMessage()),HashMap::putAll));
    }

    /**
     *
     * 参数非法异常
     *
     * @param e
     * @return
     */
    @ExceptionHandler(value = {IllegalStateException.class})
    @ResponseBody
    public Result illegalStateException(IllegalStateException e) {
        log.error("Argument not valid(Illegal):", e);
        return Result.createByErrorCodeMessage(Result.ResponseCode.BAD_REQUEST.getCode(),e.getMessage());

    }



    /**


    /**
     * ValidationException
     *
     * @return 响应体
     */
    @ExceptionHandler(ValidationException.class)
    @ResponseBody
    public Result constraintViolationExceptionHandler(ValidationException e) {
        log.error("Validation Exception: "+e);
        return Result.createByErrorCodeMessage(Result.ResponseCode.BAD_REQUEST.getCode(), e.getMessage());
    }

    /**
     * 实现对异常的拦截，当错误在Bean的注解时
     *
     * @return 响应体
     */
    @ExceptionHandler(value = {BindException.class})
    @ResponseBody
    public Result bindExceptionHandler(BindException e) {
        log.error("Bind Exception: " + e);
        log.error(JSON.toJSONString(e.getBindingResult().getAllErrors()));
        return Result.createByErrorCodeMessage(Result.ResponseCode.BAD_REQUEST.getCode(), e.getBindingResult().getFieldErrors().stream().map(FieldError::getDefaultMessage).collect(Collectors.joining(",")));
    }

}
